<template>
    <div class="editorChapterList">
        <div class="chapterList">
            <draggable class="chapterList" v-model="chapters" item-key="chapterInfo.chapterId" handle=".chapter-handle" @start="draggableChapterStart" @end="draggableChapterEnd">
                <template #item="{ element: chapter, index: cIdx }">
                    <div class="section">
                        <div class="chapterItem" :class="{ 'dragging': activeChapterIdx === cIdx && activeLessonIdx === null }">
                            <div class="chapterInfo">
                                <span class="chapter-handle infoMove" style="cursor: move;">☰</span>
                                <div class="infoNum">{{ chapter.chapterInfo?.displayOrder }}.{{ chapter.lessonInfo?.displayOrder }}</div>
                                <div class="infoName"><input type="text" v-model="chapter.chapterInfo.chapterName" placeholder="请输入章节名称" /></div>
                                <div class="editButtons">
                                    <el-popover v-if="chapter.chapterInfo?.chapterId <= 0"
                                        placement="top"
                                        trigger="hover"
                                        content="需要先保存编辑"
                                    >
                                        <template #reference>
                                            <div class="editBtn butDisable">
                                                <span class="iconfont icon-likesprogramjiexi"></span>
                                                <span class="butText">知识点管理</span>
                                            </div>
                                        </template>
                                    </el-popover>
                                    <div class="editBtn butNormal" v-else @click="showMessage('knowledgePointDialog',
                                        null, null, null, {chapterId: chapter.chapterInfo.chapterId}
                                    )">
                                        <span class="iconfont icon-likesprogramjiexi"></span>
                                        <span class="butText">知识点管理</span>
                                    </div>
                                    <div class="editBtn butNormal" @click="chapter.lessons.push({ lessonsId: 0, lessonName: '新建课时', displayOrder: chapter.lessons.length + 1})">
                                        <span class="iconfont icon-likesprogramplus"></span>
                                        <span class="butText">添加课时</span>
                                    </div>
                                    <div class="editBtn butDelete" @click="showMessage('messageDialog', '删除章节', ['确认要删除章节：' + chapter.chapterInfo?.chapterName + ' 吗？', '删除后该章节内的课时及其课时资源也会被一并删除！'], deleteChapter, chapter.chapterInfo)">
                                        <span class="iconfont icon-likesprogramhuishouzhan"></span>
                                        <span class="butText">删除</span>
                                    </div>
                                </div>
                            </div>
                            <draggable class="lessonList" v-model="chapter.lessons" item-key="lessonInfo.lessonsId" handle=".lesson-handle" 
                            :group="'lessons'" :data-section-idx="cIdx" @start="draggableLessonStart" @end="draggableLessonEnd">
                                <template #item="{ element: lesson, index: lIdx }">
                                    <div class="lessonItem" :class="{ 'dragging': activeChapterIdx === cIdx && activeLessonIdx === lIdx }">
                                        <div class="lessonInfo">
                                            <span class="lesson-handle infoMove" style="cursor: move;">☰</span>
                                            <div class="infoNum">{{ chapter.chapterInfo?.displayOrder }}.{{ lesson?.displayOrder }}</div>
                                            <div class="infoName"><input type="text" v-model="lesson.lessonName" placeholder="请输入课时名称" /></div>
                                            <div class="editButtons">
                                                <el-popover v-if="lesson?.lessonsId <= 0"
                                                    placement="top"
                                                    trigger="hover"
                                                    content="需要先保存编辑"
                                                >
                                                    <template #reference>
                                                        <div class="editBtn butDisable">
                                                            <span class="iconfont icon-likesprogramshezhi"></span>
                                                            <span class="butText">课时管理</span>
                                                        </div>
                                                    </template>
                                                </el-popover>
                                                <div class="editBtn butNormal" v-else @click="showMessage('lessonResourcesDialog', null, null, null, lesson)">
                                                    <span class="iconfont icon-likesprogramshezhi"></span>
                                                    <span class="butText">课时管理</span>
                                                </div>
                                                <div class="editBtn butDelete" @click="showMessage('messageDialog', '删除课时', ['确认要删除课时：' + lesson.lessonName + ' 吗？', '删除后该课时资源也会被一并删除！'], deleteLesson, {lessons: chapter.lessons, lesson: lesson})">
                                                    <span class="iconfont icon-likesprogramhuishouzhan"></span>
                                                    <span class="butText">删除</span>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </template>
                            </draggable>
                        </div>
                    </div>
                </template>
            </draggable>
        </div>

        <!-- 知识点管理对话框 -->
        <MessageDialog ref="knowledgePointDialog">
            <template v-slot:title>
                <span>知识点管理</span>
            </template>
            <template v-slot:content>
                <div class="dialogContent noPadding">
                    <form>
                        <div class="selectLabel">
                            <div class="inputBox maxInputBox noPadding">
                                <span>新知识点：</span>
                                <input type="text" v-model="newKnowledgePoint.knowledgeContent" placeholder="请输入知识点名称" />
                                <div class="button" :class="{ 'disable': (!newKnowledgePoint?.knowledgeContent && newKnowledgePoint?.knowledgeContent.length <= 0) }" @click="addKnowledgePoint">
                                    <span class="iconfont icon-likesprogramplus"></span>
                                    <div class="backText">添加知识点</div>
                                </div>
                            </div>
                            <div class="inputBox noPadding">
                                <span>所有内容：</span>
                                <div class="typeBox listBox maxType">
                                    <div class="typeItem" v-for="knowledge in knowledgeList" :key="knowledge.recordId">
                                        <span>{{ knowledge.knowledgeContent }}</span>
                                        <div class="button delete" @click="removeKnowledgePoint(knowledge)">
                                            <span class="iconfont icon-likesprogramhuishouzhan"></span>
                                            移除知识点
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </form>
                </div>
            </template>
            <template v-slot:footer>
                <div class="dialogFooterButton" @click="closeMessage('knowledgePointDialog')">
                    <span class="line">取消</span>
                </div>
                <div class="dialogFooterButton" @click="closeMessage('knowledgePointDialog')">
                    <span>确认</span>
                </div>
            </template>
        </MessageDialog>

        <!-- 课时管理对话框 -->
        <MessageDialog ref="lessonResourcesDialog" @closeEvent="() =>{
            
            if (currentLessonsResource !== null) {
                showMessage('messageDialog', '资源正在上传', [`你的资源正在后台上传中,你可以继续编辑其他内容，也可以等待上传完成`, '请勿刷新页面或是离开页面']);
                return;
            }
        }">
            <template v-slot:title>
                <span>课时管理</span>
            </template>
            <template v-slot:content>
                <div class="dialogContent noPadding">
                    <form>
                        <div class="inputBox">
                            <span>文件列表：</span>
                            <div class="button" @click="openFlies()"
                            :class="{ 'disable': currentLessonsResource !== null && selectLessons.lessonsId === currentLessonsResource.lessonsId }">
                                <span class="iconfont icon-likesprograma-bofangqi1"></span>
                                上传视频
                            </div>
                            <div class="button" :class="{ 'disable': currentLessonsResource !== null && selectLessons.lessonsId === currentLessonsResource.lessonsId }">
                                <span class="iconfont icon-likesprogramzhishiku"></span>
                                选择资源
                            </div>
                            <div class="button" :class="{ 'disable': currentLessonsResource !== null && selectLessons.lessonsId === currentLessonsResource.lessonsId }">
                                <span class="iconfont icon-likesprogramtianxie"></span>
                                选择习题
                            </div>
                            <!-- <div class="button" :class="{ 'butNormal': (!uploadFile || !uploadFinish), 'disable': (uploadFile || uploadFinish) }" @click="openFlies">
                                <span class="iconfont icon-likesprogrambianji"></span>
                                选择资源
                            </div> -->
                        </div>
                        <div class="inputBox" v-if="lessonResourcesList[selectLessons.lessonsId].length > 0">
                            <draggable class="draggableDataList" v-model="lessonResourcesList[selectLessons.lessonsId]" item-key="draggableData.displayOrder" handle=".draggableData-handle" 
                            @start="draggableFilesStart" @end="draggableFilesEnd">
                            <!-- @start="draggableFilesStart" @end="draggableFilesEnd" -->
                                <template #item="{ element: lessonResources, index: fIdx }">
                                    <div class="draggableData">
                                        <div class="progress" v-if="lessonResources?.progress > 0" :style="{width: lessonResources.progress + '%'}"></div>
                                        <div class="draggableDataInfo">
                                            <span class="draggableData-handle infoMove" style="cursor: move;">☰</span>
                                            <!-- <div class="infoNum">{{ lessonResources?.displayOrder }}</div> -->
                                            <div class="infoIcon">
                                                <span class="iconfont"
                                                :class="{ 'icon-likesprograma-bofangqi1' : lessonResources?.resourceType == 'video', 
                                                    'icon-likesprogramzhishiku' : lessonResources?.resourceType == 'resource',
                                                    'icon-likesprogramtianxie' : lessonResources?.resourceType == 'exercise'
                                                }"
                                                ></span>
                                                <!-- <img :src="FileProcessing.getFileIcon(uploadFile.file)" alt=""> -->
                                            </div>
                                            <div class="infoName">
                                                <span class="name">
                                                    <input type="text" v-model="lessonResources.resourceName" placeholder="请输入章节名称" />
                                                </span>
                                                <span class="urlName" v-if="lessonResources.resourceType == 'video' && (lessonResources?.progress <= 0 ||  lessonResources?.progress >= 100)"
                                                :class="{ 'error': lessonResources?.resourceUrl.length <= 0 && lessonResources?.resourceType == 'video' && lessonResources?.file == null }"
                                                >
                                                    {{ (lessonResources?.resourceUrl.length <= 0 && lessonResources?.resourceType == 'video' && lessonResources?.file == null) ? '文件未上传或上传失败' : lessonResources.resourceUrlName }}
                                                </span>
                                                <span class="urlName" v-else-if="lessonResources?.resourceType == 'video'">正在上传 {{ lessonResources.progress == null ? '...' : lessonResources.progress.toFixed(2) + '%' }}</span>
                                            </div>
                                            <div class="infoSize">{{ FileProcessing.getFileSize(lessonResources.resourceSize) }}</div>
                                            <div class="button" v-if="
                                            ((lessonResources?.resourceType == 'video' && lessonResources?.resourceUrl.length > 0) 
                                            || (lessonResources?.resourceType == 'video' && lessonResources?.file == null))
                                            && (lessonResources?.progress <= 0 ||  lessonResources?.progress >= 100)
                                            " @click="openFlies(lessonResources)">
                                                <span class="iconfont icon-likesprogramshangchuan"></span>
                                                重新上传
                                            </div>
                                            <div class="infoSize" v-else-if="lessonResources.file != null && lessonResources.progress < 0.1">等待上传</div>
                                            <div class="button delete" @click="removeFile(fIdx)">
                                                <span class="iconfont icon-likesprogramcuowu"></span>
                                                移除
                                            </div>
                                        </div>
                                    </div>
                                </template>
                            </draggable>
                        </div>
                    </form>
                </div>
            </template>
            <template v-slot:footer>
                <div class="dialogFooterButton" @click="closeMessage('lessonResourcesDialog')">
                    <span class="line">取消</span>
                </div>
                <div class="dialogFooterButton" @click="updateLessonResource()">
                    <span>确认</span>
                </div>
            </template>
        </MessageDialog>

        <!-- 提示消息对话框 -->
        <MessageDialog ref="messageDialog">
            <template v-slot:title>
                <span>{{ messageDialogData.title }}</span>
            </template>
            <template v-slot:content>
                <div class="dialogContent">
                    <div class="messageBox">
                        <div class="message" v-for=" message in messageDialogData.message">{{ message }}</div>
                    </div>
                </div>
            </template>
            <template v-slot:footer>
                <div class="dialogFooterButton" @click="closeMessage('messageDialog')">
                    <span class="line">取消</span>
                </div>
                <div class="dialogFooterButton" @click="() => {
                    messageDialogData.callBack?.(messageDialogData.callBackData)
                    closeMessage('messageDialog')
                }">
                    <span>确认</span>
                </div>
            </template>
        </MessageDialog>
    </div>
</template>

<script lang="ts">
import { courseApi, resourceApi } from '@/api/course/Course';
import { Chapter, KnowledgePoint, Lessons, LessonsResource } from '@/types/Course';
import { defineComponent, ref, watch } from 'vue';
import MessageDialog from '@/components/MessageDialog.vue';
import draggable from 'vuedraggable';
import { ElMessage } from 'element-plus';
import { FileProcessing } from '@/util/file_processing';

export default defineComponent({
    name: 'editorChapterList',
});
</script>

<script setup lang="ts">
    // 定义props
    const props = withDefaults(defineProps<{
        modelValue: {
            chapterInfo:Chapter,
            lessons: Lessons[]
        }[];
    }>(), {
        modelValue: ()=>[]
    });

    const emit = defineEmits(['update:modelValue'])

    // 本地副本用于拖拽
    const chapters = ref([...props.modelValue]);
    
    // 监听外部数据变化，保持同步
    watch(() => props.modelValue, (val) => {
      chapters.value = [...val]
    }, { deep: true })
    
    // 更新顺序
    function updateOrder() {
        chapters.value.forEach((chapter, cIdx) => {
            chapter.chapterInfo.displayOrder = cIdx + 1;
            chapter.lessons.forEach((lesson, lIdx) => {
                lesson.displayOrder = lIdx + 1;
            });
        });
        emit('update:modelValue', chapters.value)
    }
    // 消息对话框
    const messageDialog = ref(null);
    const knowledgePointDialog = ref(null);
    const lessonResourcesDialog = ref(null);
    const messageDialogData = ref<{
        title: string,
        message: string[],
        callBack?: (data: any) => void,
        callBackData?: any
    }>();
    const knowledgeList  = ref<KnowledgePoint[]>([]);
    const createNewKnowledgePoint = () => {
        return {
            courseId: 0,
            recordId: 0,
            cameraId: 0,
            quoteRecordId: 0,
            quoteTime: '',
            recordType: '',
            recordUrl: '',
            knowledgeContent: '',
            fileSize: '',
            isPublic: false,
            uploadBy: 0,
            uploadTime: '',
            recordRemark: ''
        }
    }
    const newKnowledgePoint = ref<KnowledgePoint>(createNewKnowledgePoint());

    // 当前更新课时资源名称
    const currentLessonsResource = ref<Lessons>(null);
    const selectLessons = ref<Lessons>(null);
    // 课时资源列表
    const lessonResourcesList = ref<Record<number, LessonsResource[]>>({});

    const showMessage = async (dialongName: string, title?: string, message?: string[], callBack?: (data: any) => void, callBackData?: any) => {
        switch (dialongName) {
            case 'messageDialog':
                messageDialogData.value = {title, message, callBack, callBackData};
                messageDialog.value.ShowModal();
                break;
            case 'knowledgePointDialog':
                newKnowledgePoint.value = createNewKnowledgePoint();
                knowledgeList.value = (await courseApi.chapter.knowledge.getKnowledgePoint(null, callBackData?.chapterId)).data;
                newKnowledgePoint.value.cameraId = callBackData?.chapterId;
                knowledgePointDialog.value.ShowModal();
                break;
            case 'lessonResourcesDialog':
            {
                if(!lessonResourcesList.value[callBackData?.lessonsId]?.length)
                {
                    console.log(callBackData?.lessonsId);
                    console.log(lessonResourcesList.value[callBackData?.lessonId]);
                    let lastProgress = 0.01;
                    const resources = (await courseApi.chapter.lessons.getLessonResource(callBackData?.lessonsId)).data;
                    const result: any[] = [];
                    for (const item of resources) {
                        const progress = await resourceApi.files.getProgress("upload_lessons_resource_" + item.resourceId);
                        if ((lastProgress > 0 && lastProgress < 100) && progress == 0 && item.resourceUrl?.length <= 0) {
                            item.progress = 0.01;
                        } else {
                            item.progress = progress;
                        }
                        lastProgress = item.progress;
                        console.log(item);
                        result.push(item);
                    }
                    lessonResourcesList.value[callBackData?.lessonsId] = result;
                }
                lessonResourcesDialog.value.ShowModal();
                selectLessons.value = callBackData;
                break;
            }
        }
    }
    const closeMessage = (dialongName: string) => {
        switch (dialongName) {
            case 'messageDialog':
                messageDialog.value.Close();
                break;
            case 'knowledgePointDialog':
                knowledgePointDialog.value.Close();
                break;
            case 'lessonResourcesDialog':
                lessonResourcesDialog.value.Close();
                break;
        }
    }

    // 添加知识点
    const addKnowledgePoint = async () => { 
        if((await courseApi.chapter.knowledge.addKnowledgePoint(newKnowledgePoint.value)).data)
        {
            ElMessage.success('添加成功');
            knowledgeList.value = (await courseApi.chapter.knowledge.getKnowledgePoint(null, newKnowledgePoint.value.cameraId)).data;
            newKnowledgePoint.value.knowledgeContent = '';
        } else
        {
            ElMessage.error('添加失败');
        }
    }

    // 移除知识点
    const removeKnowledgePoint = async (data: KnowledgePoint) => {
        if (await courseApi.chapter.knowledge.removeKnowledgePoint(data)) {
            ElMessage.success('删除成功');
            knowledgeList.value = (await courseApi.chapter.knowledge.getKnowledgePoint(null, newKnowledgePoint.value.cameraId)).data;
        } else {
            ElMessage.error('删除失败');
        }
    }

    // 删除章节
    const deleteChapter = (data: any) => {
        chapters.value.splice(data.displayOrder - 1, 1);
        updateOrder();
    }

    // 删除课时
    const deleteLesson = (data: any) => {
        console.log(data);
        data.lessons.splice(data.lesson.displayOrder - 1, 1);
    }

    function updateLessonsResourceOrder() {
        lessonResourcesList.value[selectLessons.value.lessonsId].forEach((resource, Idx) => {
            resource.displayOrder = Idx + 1;
        });
    }

    const draggableFilesStart = () => {
        setTimeout(() => {
            // activeUploadFileIdx.value = e.oldIndex;
        }, 0);
    }
    const draggableFilesEnd = () => {
        // activeUploadFileIdx.value = null;
        updateLessonsResourceOrder();
    }
    const updateLocalLessonResource = async () =>{
        const localResources = lessonResourcesList.value[currentLessonsResource.value.lessonsId];
        const resources = (await courseApi.chapter.lessons.getLessonResource(currentLessonsResource.value.lessonsId)).data;
        
        // 同步更新
        for (let i = 0; i < localResources.length; i++) {
            const local = localResources[i];
            const remote = resources.find(r => r.displayOrder === local.displayOrder);
            if (remote) {
                local.resourceId = remote.resourceId;
                local.lessonsId = remote.lessonsId;
                local.resourceType = remote.resourceType;
                local.resourceName = remote.resourceName;
                local.displayOrder = remote.displayOrder;
                local.resourceLink = remote.resourceLink;
                local.resourceUrlName = remote.resourceUrlName;
                local.resourceUrl = remote.resourceUrl;
                local.resourceSize = remote.resourceSize;
                local.durationSeconds = remote.durationSeconds;
                local.createDate = remote.createDate;
                local.updateDate = remote.updateDate;
            }
        }
    }
    // 上传课时资源文件
    const uploadLessonFiles = async (lessonsResponse:LessonsResource[]) => {
        console.log(lessonsResponse)
        for (const lessonResources of lessonsResponse) {
            if (lessonResources.resourceId && lessonResources.resourceType == 'video') {
                if(lessonResources.file == null) continue;
                let startUpload = false;
                let uploadStatus = 0;
                courseApi.chapter.lessons.uploadFile(
                    lessonResources.file,
                    lessonResources.resourceId,
                    async (progress) => {
                        lessonResources.progress = progress;
                        if (lessonResources.progress === 100) startUpload = true;
                    }
                ).then(async ()=> {
                    await updateLocalLessonResource();
                    lessonResources.file = null;
                    lessonResources.progress = 0;
                    let haveFile = 0;
                    for(let resource of lessonsResponse) if(resource.file != null) haveFile++;
                    if(haveFile <= 0) setTimeout(() => {
                        currentLessonsResource.value = null;
                        closeMessage("lessonResourcesDialog");
                        ElMessage.success("保存成功");
                    }, 1000);
                }).catch(()=> {
                    uploadStatus = -1;
                });
            
                // 获取进度
                lessonResources.progress = 0;
                while (true) {
                    // 等待上传开始
                    if (!startUpload)
                    {
                        await new Promise(resolve => setTimeout(resolve, 1000));
                        continue
                    }
                    if (uploadStatus === -1) {
                        break;
                    }
                    lessonResources.progress = await resourceApi.files.getProgress("upload_lessons_resource_" + lessonResources.resourceId).catch(() => -1);
                    if (lessonResources.progress === -1) {
                        console.warn("进度获取失败，但不代表上传失败，继续重试");
                        uploadStatus = -1;
                        break;
                    }
                    if (lessonResources.progress === 100) {
                        break;
                    }
                    await new Promise(resolve => setTimeout(resolve, 1000));
                }
            }
        }
        
        let haveFile = 0;
        for(let resource of lessonsResponse) if(resource.file != null) haveFile++;
        if(haveFile <= 0) setTimeout(() => {
            currentLessonsResource.value = null;
            closeMessage("lessonResourcesDialog");
            ElMessage.success("保存成功");
        }, 1000);
    }
    // 跟新课时资源
    const updateLessonResource = async () => {
        if (currentLessonsResource.value !== null) {
            showMessage('messageDialog', '正在更新课时资源...', [`当前正在更新课时[${currentLessonsResource.value.lessonName}],请耐心等待！`]);
            return;
        }
        currentLessonsResource.value = selectLessons.value;

        await courseApi.chapter.lessons.updateLessonResource(currentLessonsResource.value.lessonsId, lessonResourcesList.value[currentLessonsResource.value.lessonsId]);
        await updateLocalLessonResource();
        uploadLessonFiles(lessonResourcesList.value[currentLessonsResource.value.lessonsId]);
    }
    // 打开文件
    const openFlies = (resources?: LessonsResource) => {
        if (currentLessonsResource.value !== null) return;
        FileProcessing.openFiles('video/*', false)
        .then(async (file) => {
            if (resources?.lessonsId)
            {
                resources.resourceUrlName = '';
                resources.resourceUrl = '';
                resources.file = file as File;
                resources.resourceSize = (file as File).size;
                resources.durationSeconds = await FileProcessing.getVideoDuration(file as File).catch(() => -1);
            }
            else 
            {
                // 确保数组初始化
                if (!lessonResourcesList.value[selectLessons.value.lessonsId]?.length) {
                    lessonResourcesList.value[selectLessons.value.lessonsId] = [];
                }

                // 获取当前数组引用
                const currentResources = lessonResourcesList.value[selectLessons.value.lessonsId];

                // 计算新元素的序号
                const newIndex = currentResources.length + 1;

                currentResources.push({
                    resourceId: 0,
                    lessonsId: selectLessons.value.lessonsId,
                    file: file as File,
                    resourceType: 'video',
                    resourceName: `视频${newIndex}`,
                    displayOrder: newIndex,
                    resourceLink: 0,
                    resourceUrlName: '',
                    resourceUrl: '',
                    resourceSize: (file as File).size,
                    durationSeconds: await FileProcessing.getVideoDuration(file as File),
                    createDate: '',
                    updateDate: ''
                });
            }
        });
    }
    // 移除文件
    const removeFile = (idx: number) => {
        lessonResourcesList.value[selectLessons.value.lessonsId].splice(idx, 1);
        updateLessonsResourceOrder();
    }

    // 拖拽事件
    const activeChapterIdx = ref(null);
    const activeLessonIdx = ref(null);
    const draggableChapterStart = (e: any) => {
        setTimeout(() => {
            activeChapterIdx.value = e.oldIndex;
            activeLessonIdx.value = null;
        }, 0);
    }
    const draggableChapterEnd = () => {
        activeChapterIdx.value = null;
        activeLessonIdx.value = null;
        updateOrder();
    }
    const draggableLessonStart = (e: any) => {
        setTimeout(() => {
            console.log(e.from.dataset.sectionIdx)
            activeChapterIdx.value = e.from.dataset.sectionIdx ? Number(e.from.dataset.sectionIdx) : e.from.sectionIdx
            activeLessonIdx.value = e.oldIndex
        }, 0);
    }
    const draggableLessonEnd = () => {
        activeChapterIdx.value = null;
        activeLessonIdx.value = null;
        updateOrder();
    }
</script>

<style src="@/assets/icons/iconfont.css" scoped></style>

<style scoped>
.editorChapterList {
    width: 100%;
    height: 100%;
    position: relative;
}

.editorChapterList .chapterList {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: center;
    overflow-y: auto;
}

.editorChapterList .chapterList .section {
    width: 80%;
    --color: rgba(0, 0, 0, 1);
    --background-color: rgba(255, 255, 255, .5);
}
.editorChapterList .chapterList .section .dragging {
    --color: rgba(150, 150, 150, .1);
    --background-color: rgba(200, 200, 200, .5);
}

.editorChapterList .chapterList .section .chapterItem {
    width: 100%;
    border-radius: 10px;
    margin: 10px 0px;
    box-shadow: 2px 2px 6px rgba(0, 0, 0, .1);
    display: flex;
    overflow: hidden;
    flex-direction: column;
    justify-content: flex-start;
    align-items: flex-start;
    background-color: var(--background-color);
    backdrop-filter: blur(2rem);
    -webkit-backdrop-filter: blur(2rem);
    -moz-backdrop-filter: blur(2rem);
    -ms-backdrop-filter: blur(2rem);
}

/* 章节信息 */
.editorChapterList .chapterList .chapterItem .chapterInfo {
    width: 100%;
    padding-right: 20px;
    font-size: 16px;
    gap: 10px;
    display: flex;
    justify-content: flex-start;
    align-items: center;
    color: var(--color);
    background-color: var(--background-color);
}
.editorChapterList .chapterList .chapterItem .chapterInfo .infoName input {
    font-size: 16px;
}
.editorChapterList .chapterList .infoMove {
    flex-shrink: 0;
    width: 45px;
    height: 45px;
    display: flex;
    justify-content: center;
    align-items: center;
}
.editorChapterList .chapterList .infoNum {
    flex-shrink: 0;
}
.editorChapterList .chapterList .infoName {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dialogContent form .inputBox .name input,
.editorChapterList .chapterList .infoName input {
    width: 100%;
    height: 30px;
    outline: none;
    border: none;
    color: var(--color);
    background-color: rgba(255, 255, 255, 0);
}
.editorChapterList .chapterList .infoName input:focus {
    padding: 0px 10px;
    outline: none;
    border: 2px solid rgba(65, 185, 255, 1);
    border-radius: 5px;
}

/* 操作按钮 */
.editorChapterList .chapterList .editButtons {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    flex-shrink: 0;
    gap: 10px;
}

.editorChapterList .chapterList .editButtons .editBtn {
    font-size: 18px;
    padding: 0px 10px;
    border-radius: 5px;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 5px;
    transition: all .3s;
}
.editorChapterList .chapterList .editButtons .editBtn .butText {
    font-size: 12px;
}
/* 正常按钮 */
.editorChapterList .chapterList .editButtons .editBtn.butNormal {
    color: rgba(255, 255, 255, 1);
    background-color: rgba(65, 185, 255, 1);
}
.editorChapterList .chapterList .editButtons .editBtn.butNormal:hover {
    color: rgba(255, 255, 255, 1);
    background-color: rgba(65, 185, 255, .8);
}
.editorChapterList .chapterList .editButtons .editBtn.butNormal:active {
    color: rgba(255, 255, 255, 1);
    background-color: rgba(65, 185, 255, .9);
    transition: all .1s;
}
/* 删除按钮 */
.editorChapterList .chapterList .editButtons .editBtn.butDelete {
    color: rgba(255, 255, 255, 1);
    background-color: rgba(255, 0, 0, 1);
}
.editorChapterList .chapterList .editButtons .editBtn.butDelete:hover {
    color: rgba(255, 255, 255, 1);
    background-color: rgba(255, 0, 0, .7);
}
.editorChapterList .chapterList .editButtons .editBtn.butDelete:active {
    color: rgba(255, 255, 255, 1);
    background-color: rgba(255, 0, 0, .9);
    transition: all .1s;
}
/* 失效按钮 */
.editorChapterList .chapterList .editButtons .editBtn.butDisable {
    color: rgba(255, 255, 255, 1);
    background-color: rgba(185, 185, 185, 1);
}

.editorChapterList .chapterList .dragging .editButtons .editBtn {
    color: var(--color);
    background-color: var(--background-color);
}
/* 课时列表 */
.editorChapterList .chapterList .chapterItem .lessonList {
    width: 100%;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: flex-start;
    gap: 10px;
    padding: 10px;
}
.editorChapterList .chapterList .chapterItem .lessonList .lessonItem {
    width: 100%;
    padding-right: 20px;
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 2px 2px 6px rgba(0, 0, 0, .1);
    display: flex;
    justify-content: flex-start;
    align-items: center;
    background-color: var(--background-color);
    transition: all .3s;
}
.editorChapterList .chapterList .chapterItem .lessonList .lessonItem .lessonInfo {
    width: 100%;
    gap: 10px;
    font-size: 14px;
    color: var(--color);
    display: flex;
    justify-content: flex-start;
    align-items: center;
}
.editorChapterList .chapterList .chapterItem .lessonList .lessonItem .lessonInfo .infoName input {
    font-size: 14px;
}

.dialogContent {
    width: 100%;
    height: 100%;
    padding: 20px;
    display: flex;
    justify-content: center;
    align-items: center;
}
.dialogContent.noPadding {
    padding: 0px;
}

/* 编辑课程对话框 */
.dialogContent form {
    width: 600px;
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    align-items: center;
}

.dialogContent form .inputBox {
    width: 550px;
    padding: 10px 0px;
    font-size: 16px;
    display: flex;
    justify-content: flex-start;
    align-items: center;
}

.dialogContent form .inputBox.noPadding {
    padding: 10px 0px;
    align-items: flex-start;
}

/* 输入框 */
.dialogContent form .inputBox span {
    min-width: 80px;
}

.dialogContent form .inputBox input,
.dialogContent form .inputBox textarea {
    width: 100%;
    height: 35px;
    font-size: 16px;
    border: 2px solid rgba(200, 200, 200, 1);
    border-radius: 5px;
    padding: 0px 10px;
    outline: none;
}

.dialogContent form .inputBox.noPadding textarea {
    height: 100px;
    resize: none;
    /* 禁止调整大小 */
    padding: 3px 10px;
    line-height: 28px;
}

.dialogContent form .inputBox input:focus,
.dialogContent form .inputBox textarea:focus {
    border: 2px solid rgba(65, 185, 255, 1);
}

.dialogContent form .inputBox input,
.dialogContent form .inputBox .typeBox {
    width: 100%;
    font-size: 14px;
    border-radius: 5px;
    padding: 0px 10px;
    outline: none;
    overflow-y: auto;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
    gap: 10px;
}

.dialogContent form .inputBox .selectBox,
.dialogContent form .inputBox input {
    height: 35px;
    border: 2px solid rgba(200, 200, 200, 1);
}

.dialogContent form .inputBox .typeBox {
    min-height: 40px;
    max-height: 80px;
    resize: none;
    /* 禁止调整大小 */
    padding: 0px;
    line-height: 28px;
    display: flex;
    flex-wrap: wrap;
    gap: 0px;
}

.dialogContent form .inputBox .typeBox.maxType {
    max-height: 250px;
}

.dialogContent form .inputBox .typeBox.slectList {
    max-height: 150px;
}

.dialogContent form .inputBox input:focus {
    border: 2px solid rgba(65, 185, 255, 1);
}

.dialogContent form .inputBox .listBox {
    border: 2px solid rgba(200, 200, 200, 1);
}

/* 列表 */
.dialogContent form .inputBox .typeBox .typeItem {
    display: flex;
    justify-content: space-between;
    align-items: center;
    /* 单行溢出省略 */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    width: 100%;
    font-size: 14px;
    padding: 5px 10px;
    border-bottom: 1px solid rgba(200, 200, 200, 1);
}

.dialogContent form .inputBox .typeBox.slectList .typeItem {
    color: rgba(65, 185, 255, 1);
    border: 2px solid rgba(65, 185, 255, 1);
}

.dialogContent form .inputBox .typeBox .typeItem.select {
    color: rgb(255, 255, 255);
    border: 2px solid rgba(65, 185, 255, 1);
    background: rgba(65, 185, 255, 1);
}

/* 表单按钮 */
.dialogContent form .inputBox .button {
    flex-shrink: 0;
    padding: 0px 10px;
    gap: 5px;
    height: 35px;
    overflow: hidden;
    border-radius: 5px;
    margin-left: 10px;
    transition: .3s all;
    display: flex;
    justify-content: center;
    align-items: center;
    color: aliceblue;
    background-color: rgba(65, 185, 255, 1);
}
.dialogContent form .inputBox .button span {
    min-width: 0px;
}
.dialogContent form .inputBox .button .iconfont {
    font-size: 20px;
}

/* 表单按钮 */
.dialogContent form .inputBox .button:hover {
    background-color: rgba(65, 185, 255, 0.8);
}

.dialogContent form .inputBox .button:active {
    transition: .1s all;
    background-color: rgba(65, 185, 255, 1);
}

/* 禁用按钮 */
.dialogContent form .inputBox .button.disable {
    color: aliceblue;
    background-color: rgba(180, 180, 180, 1);
}

.dialogContent form .inputBox .button.disable:hover {
    background-color: rgba(180, 180, 180, 0.8);
}

.dialogContent form .inputBox .button.disable:active {
    transition: .1s all;
    background-color: rgba(180, 180, 180, 1);
}

/* 禁用按钮 */
.dialogContent form .inputBox .button.delete {
    color: aliceblue;
    background-color: rgb(255, 0, 0);
}

.dialogContent form .inputBox .button.delete:hover {
    background-color: rgba(255, 0, 0, 0.8);
}

.dialogContent form .inputBox .button.delete:active {
    transition: .1s all;
    background-color: rgb(255, 0, 0);
}

/* 下拉框 */
.dialogContent form .inputBox .selectBox {
    width: 100%;
    border-radius: 5px;
    font-size: 16px;
    padding: 0px 0px;
    color: #333;
    outline: none;
    position: relative;
    cursor: pointer;
    display: flex;
    background-color: rgba(0, 0, 0, 0);
    justify-content: space-between;
    transition: .3s all;
}
.dialogContent form .inputBox .selectBox:focus-within {
    border: 2px solid rgba(65, 185, 255, 1);
}
.dialogContent form .inputBox .selectBox:focus-within .iconfont {
    color: rgba(65, 185, 255, 1);
}
.dialogContent form .inputBox .selectBox .select {
    width: 100%;
    padding: 0px 10px;
    padding-right: 35px;
    border: 0px solid #ccc;
    border-radius: 4px;
    background-color: rgba(0, 0, 0, 0);
    font-size: 14px;
    position: relative;
    z-index: 1;
    color: #333;
    outline: none;
    cursor: pointer;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
}
.dialogContent form .inputBox .selectBox .iconfont {
    width: 30px;
    min-width: 0px;
    font-size: 20px;
    position: absolute;
    right: 2px;
    display: flex;
    justify-content: center;
    align-items: center;
    transform: rotate(-90deg);
    transition: .3s all;
    color: rgba(100, 100, 100, 1);
}

/* 拖拽数据列表 */
.dialogContent form .inputBox .draggableDataList {
    width: 100%;
    max-height: 300px;
    border: 2px solid rgba(200, 200, 200, 1);
    border-radius: 5px;
    padding: 5px;
    overflow-y: auto;
}
.dialogContent form .inputBox .draggableDataList span {
    min-width: 0px;
}
.dialogContent form .inputBox .draggableDataList .draggableData {
    width: 100%;
    height: 55px;
    border-radius: 5px;
    overflow: hidden;
    position: relative;
}
.dialogContent form .inputBox .draggableDataList .draggableData .progress {
    height: 50%;
    top: 50%;
    transform: translateY(-50%) translateX(0px);
    position: absolute;
    border-radius: 5px;
    z-index: 1;
    background-color: rgba(65, 185, 255, .5);
}
.dialogContent form .inputBox .draggableDataList .draggableData .draggableDataInfo {
    width: 100%;
    height: 100%;
    border-radius: 5px;
    padding-right: 5px;
    z-index: 2;
    position: relative;
    display: flex;
    justify-content: space-between;
    align-items: center;
    background-color: rgba(255, 255, 255, .5);
    backdrop-filter: blur(.5rem);
    -webkit-backdrop-filter: blur(.5rem);
    -moz-backdrop-filter: blur(.5rem);
    -ms-backdrop-filter: blur(.5rem);
}
.dialogContent form .inputBox .draggableDataList .draggableData .draggableDataInfo .infoMove {
    flex-shrink: 0;
    width: 45px;
    height: 55px;
    min-width: 0px;
    display: flex;
    justify-content: center;
    align-items: center;
}
.dialogContent form .inputBox .draggableDataList .draggableData .draggableDataInfo .infoNum {
    flex-shrink: 0;
    padding: 0px 10px;
    min-width: 0px;
    display: flex;
    justify-content: center;
    align-items: center;
}
.dialogContent form .inputBox .draggableDataList .draggableData .draggableDataInfo .infoIcon {
    flex-shrink: 0;
    min-width: 0px;
    display: flex;
    justify-content: center;
    
}
.dialogContent form .inputBox .draggableDataList .draggableData .draggableDataInfo .infoIcon img {
    width: 25px;
    height: 25px;
}
.dialogContent form .inputBox .draggableDataList .draggableData .draggableDataInfo .infoIcon .iconfont {
    font-size: 26px;
}
.dialogContent form .inputBox .draggableDataList .draggableData .draggableDataInfo .infoName {
    flex: 1;
    padding: 0px 5px;
    min-width: 0px;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: flex-start;
}.dialogContent form .inputBox .draggableDataList .draggableData .drggableDataInfo .infoName .name {
    font-size: 15px;
    display: flex;
    justify-content: flex-start;
    align-items: flex-start;
}.dialogContent form .inputBox .draggableDataList .draggableData .draggableDataInfo .infoName .urlName {
    padding: 0px 15px;
    max-height: 12px;
    font-size: 12px;
    color: rgba(0, 0, 0, 0.6);
    display: flex;
    justify-content: flex-start;
    align-items: center;
}
.dialogContent form .inputBox .draggableDataList .draggableData .draggableDataInfo .infoName .urlName.error {
    color: rgb(255, 0, 0);
}
.dialogContent form .inputBox .draggableDataList .draggableData .draggableDataInfo .infoType {
    flex-shrink: 0;
    max-width: 150px;
    padding: 0px 5px;
    min-width: 0px;
    display: flex;
    justify-content: flex-start;
    align-items: center;
}
.dialogContent form .inputBox .draggableDataList .draggableData .draggableDataInfo .infoSize {
    flex-shrink: 0;
    max-width: 100px;
    min-width: 0px;
    padding: 0px 5px;
    display: flex;
    justify-content: center;
    align-items: center;
}
.dialogContent form .inputBox .draggableDataList .draggableData .draggableDataInfo .infoName span,
.dialogContent form .inputBox .draggableDataList .draggableData .draggableDataInfo .infoType span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dialogContent form .inputBox .draggableDataList .draggableData .draggableDataInfo .button {
    font-size: 14px;
    min-width: 0px;
    height: 25px;
    padding: 0px 5px;
}
.dialogContent form .inputBox .draggableDataList .draggableData .draggableDataInfo .button .iconfont {
    font-size: 16px;
    margin-right: 2px;
}
.dialogContent form .inputBox .draggableDataList .draggableData .draggableDataInfo .infoType.fail {
    color: rgba(255, 0, 0, 1);
}
.dialogContent form .inputBox .draggableDataList .draggableData .draggableDataInfo .infoType.warning {
    color: rgb(255, 145, 0);
}
.dialogContent form .inputBox .draggableDataList .draggableData .draggableDataInfo .infoType.success {
    color: rgba(65, 185, 255, 1)
}

/* 对话框底部按钮 */
.dialogFooterButton {
    width: 100%;
    height: 65px;
    position: relative;
    display: flex;
    color: rgba(65, 185, 255, 1);
    justify-content: center;
    align-items: center;
    cursor: pointer;
    transition: .3s all;
}
.dialogFooterButton:hover {
    background-color: rgba(200, 200, 200, .15);
}
.dialogFooterButton:active {
    transition: .1s all;
    background-color: rgba(220, 220, 220, .1);
}
.dialogFooterButton .line {
    width: 100%;
    border-right: 1px solid rgba(200, 200, 200, 1);
    display: flex;
    justify-content: center;
    align-items: center;
}
</style>
